package com.xgq.drink.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xgq.drink.entity.*;
import com.xgq.drink.mapper.BrandMapper;
import com.xgq.drink.mapper.UserMapper;
import com.xgq.drink.mapper.RoleMapper;
import com.xgq.drink.mapper.UserRoleMapper;
import com.xgq.drink.utils.RUtils;
import com.xgq.drink.utils.RedisUtil;
import com.xgq.drink.utils.UniqueIdGenerator;
import com.xgq.drink.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author XuGuiQi
 * @since 2025-02-22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Override
    public User GetUserByUsername(String name) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", name);
        return userMapper.selectOne(wrapper);
    }
    @Override
    public User GetUserByUserId(String id) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", id);
        return userMapper.selectOne(wrapper);
    }

    @Override
    public User login(User user) {
        try {
            User userDB = userMapper.getUserByUsernameOrPhone(user.getUsername());
            if (userDB == null) {
                throw new RuntimeException("用户不存在");
            }
            if (!passwordEncoder.matches(user.getPassword(), userDB.getPassword())) {
                throw new RuntimeException("密码错误");
            }
            List<Role> roles = userRoleMapper.selectRolesByUserId(userDB.getUserId());
            if (roles == null || roles.isEmpty()) {
                throw new RuntimeException("用户没有任何角色");
            }
            try {
                redisUtil.setUserRoles(userDB.getUserId().toString(), roles);
                return userDB;
            } catch (Exception e) {
                throw new RuntimeException("Redis操作失败: " + e.getMessage(), e);
            }
        } catch (Exception e) {
            System.out.println("登录过程发生异常: " + e.getClass().getName() + ": " + e.getMessage());
            throw new RuntimeException("登录失败: " + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R register(LoginUser loginUser) {
        String key = "sms:" + loginUser.getUser().getPhone();
        String storedCode = redisUtil.get(key);
        if (storedCode == null || !storedCode.equals(loginUser.getCode())) {
            return RUtils.fail("验证码错误！");
        }
        if (userMapper.selectOne(new QueryWrapper<User>().eq("phone", loginUser.getUser().getPhone())) != null) {
            return RUtils.fail("手机号已存在");
        }
        long uniqueId = UniqueIdGenerator.generateUniqueId();
        loginUser.getUser().setUserId(uniqueId);
        UUID uuid = UUID.randomUUID();
        loginUser.getUser().setUsername(uuid.toString().replaceAll("-", ""));
        String encryptedPassword = passwordEncoder.encode(loginUser.getUser().getPassword());
        int result = userMapper.insert(loginUser.getUser());
        if (result > 0) {
            UserRole userRoleRelation = new UserRole();
            userRoleRelation.setUserId(uniqueId);
            userRoleRelation.setRoleId(5L);
            userRoleMapper.insert(userRoleRelation);
            return RUtils.success("注册成功");
        } else {
            return RUtils.fail("注册失败");
        }
    }
    @Override
    public R updateUser(User user, String code) {
        // 检查用户ID是否为空
        if (user.getUserId() == null) {
            return RUtils.fail("用户ID不能为空");
        }

        // 创建UpdateWrapper
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_id", user.getUserId());
        // 如果密码不为空，则需要验证验证码
        if (StringUtils.isNotBlank(user.getPassword())) {
            // 从 Redis 中获取验证码
            String key = "sms:" + user.getPhone();
            String storedCode = redisUtil.get(key);

            // 验证验证码是否正确
            if (storedCode == null || !storedCode.equals(code)) {
                return RUtils.fail("验证码错误");
            }

            String encryptedPassword = passwordEncoder.encode(user.getPassword());
            updateWrapper.set("password", encryptedPassword);
        }


        // 动态构建更新语句，忽略空值或空白字符串
        if (StringUtils.isNotBlank(user.getUsername())) {
            updateWrapper.set("username", user.getUsername());
        }
        if (StringUtils.isNotBlank(user.getEmail())) {
            updateWrapper.set("email", user.getEmail());
        }
        if (StringUtils.isNotBlank(user.getPhone())) {
            updateWrapper.set("phone", user.getPhone());
        }
        if (StringUtils.isNotBlank(user.getAvatarUrl())) {
            updateWrapper.set("avatar_url", user.getAvatarUrl());
        }
        // 如果没有需要更新的字段，则直接返回
        if (updateWrapper.getSqlSet() == null || updateWrapper.getSqlSet().isEmpty()) {
            return RUtils.fail("没有需要更新的字段");
        }
        // 执行更新操作
        int result = userMapper.update(null, updateWrapper);
        if (result > 0) {
            return RUtils.success("用户信息更新成功");
        } else {
            return RUtils.fail("用户信息更新失败");
        }
    }
    @Override
    public User loginByPhone(String phone, String code) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone);
        User userDB = userMapper.selectOne(wrapper);
        if (userDB == null) {
            throw new RuntimeException("登录失败：手机号不存在");
        }
        if (code == null || code.trim().isEmpty()) {
            throw new RuntimeException("登录失败：验证码为空");
        }
        String key = "sms:" + phone;
        String storedCode = redisUtil.get(key);
        if (storedCode == null) {
            throw new RuntimeException("登录失败：验证码已过期或不存在");
        }
        if (!storedCode.equals(code)) {
            throw new RuntimeException("登录失败：验证码错误");
        }
        List<Role> roles = userRoleMapper.selectRolesByUserId(userDB.getUserId());
        if (roles == null || roles.isEmpty()) {
            throw new RuntimeException("用户没有任何角色");
        }
        try {
            redisUtil.setUserRoles(userDB.getUserId().toString(), roles);
            return userDB;
        } catch (Exception e) {
            throw new RuntimeException("Redis操作失败: " + e.getMessage(), e);
        }
    }

    // 分配角色给用户
    @Transactional(rollbackFor = Exception.class)
    public void assignRole(Long userId, Long roleId, Long brandId) {
        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查角色是否存在
        Role role = roleMapper.selectById(roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }

        // 创建用户角色关联
        UserRole userRole = new UserRole();
        userRole.setUserId(userId);
        userRole.setRoleId(roleId);
        userRole.setBrandId(brandId);

        userRoleMapper.insert(userRole);
        // 更新Redis中的用户角色信息
        List<Role> roles = userRoleMapper.selectRolesByUserId(userId);
        redisUtil.setUserRoles(userId.toString(), roles);
    }

    // 移除用户角色
    @Transactional(rollbackFor = Exception.class)
    public void removeRole(Long userId, Long roleId, Long brandId) {
        QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId)
                .eq("role_id", roleId)
                .eq(brandId != null, "brand_id", brandId);

        userRoleMapper.delete(wrapper);
        // 更新Redis中的用户角色信息
        List<Role> roles = userRoleMapper.selectRolesByUserId(userId);
        redisUtil.setUserRoles(userId.toString(), roles);
    }

    // 检查用户是否具有某个角色
    public boolean hasRole(Long userId, String roleCode) {
        List<Role> roles = userRoleMapper.selectRolesByUserId(userId);
        return roles.stream().anyMatch(role -> role.getCode().equals(roleCode));
    }

    // 检查用户是否具有某个品牌的特定角色
    public boolean hasBrandRole(Long userId, Long brandId, String roleCode) {
        QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId)
                .eq("brand_id", brandId);
        List<UserRole> userRoles = userRoleMapper.selectList(wrapper);
        
        return userRoles.stream()
                .map(userRole -> roleMapper.selectById(userRole.getRoleId()))
                .anyMatch(role -> role.getCode().equals(roleCode));
    }
    //  角色校验部分
    public boolean validateStorePermission(String userId, Long storeId) {
        // 验证用户是否在指定店铺拥有有效角色
        System.out.println("--==--");
        System.out.println(userId);
        System.out.println(storeId);
        return userRoleMapper.exists(
                new QueryWrapper<UserRole>()
                        .eq("brand_id", storeId)
                        .eq("user_id", userId)
                        .in("role_id", Arrays.asList(3, 4))
        );
    }
    @Override
    public List<Brand> getUserBrands(Long userId) {
        // 通过用户角色关联查询品牌ID
        List<Long> brandIds = userRoleMapper.selectList(
                        new QueryWrapper<UserRole>()
                                .select("brand_id")
                                .eq("user_id", userId)
                                .in("role_id", 3,4)
                ).stream()
                .map(UserRole::getBrandId)
                .distinct()
                .collect(Collectors.toList());

        if (brandIds.isEmpty()) return Collections.emptyList();

        // 查询有效品牌（保持与BrandServiceImpl相同的查询条件）
        return brandMapper.selectList(
                new QueryWrapper<Brand>()
                        .in("brand_id", brandIds)
                        .eq("is_deleted", 0) // 假设1为有效状态
        );
    }
    @Override
    public Brand GetBrandByUserId(Long id) {
        QueryWrapper<Brand> wrapper = new QueryWrapper<>();
        wrapper.eq("brand_id", id);
        return brandMapper.selectOne(wrapper);
    }
    public Brand GetBrandByUserIdAndBrandId(Long userId, Long brandId) {
        QueryWrapper<Brand> wrapper = new QueryWrapper<>();
        wrapper.eq("brand_id", userId);
//        wrapper.eq("user_id", brandId);
        return brandMapper.selectOne(wrapper);
    }

    @Override
    public R updatePassword(String userId, String phone, String code, String newPassword) {
        try {
            // 1. 验证用户存在性
            User user = baseMapper.selectById(userId);
            if (user == null) {
                return RUtils.fail("用户不存在");
            }

            // 2. 验证手机号匹配
            if (!user.getPhone().equals(phone)) {
                return RUtils.fail("手机号与账号不匹配");
            }

            // 3. 验证短信验证码
            String redisKey = "sms:" + phone;
            String storedCode = redisUtil.get(redisKey);
            if (storedCode == null || !storedCode.equals(code)) {
                return RUtils.fail("验证码错误或已过期");
            }

            // 4. 更新密码
            user.setPassword(passwordEncoder.encode(newPassword));
            baseMapper.updateById(user);

            return RUtils.success("密码修改成功");
        } catch (Exception e) {
            return RUtils.fail("密码修改失败: " + e.getMessage());
        }
    }

    @Override
    public R updateUserInfo(User user) {
        try {
            // 1. 防止更新敏感字段
            user.setPassword(null);
            user.setIsActive(null);

            // 2. 执行更新
            boolean success = updateById(user);
            return success ? RUtils.success("信息更新成功") : RUtils.fail("信息未发生变化");
        } catch (Exception e) {
            return RUtils.fail("信息更新失败: " + e.getMessage());
        }
    }
}
